package com.weixing.mall.provider.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.mall.base.enums.IdGenTagEnum;
import com.weixing.mall.base.enums.ResultCodeEnum;
import com.weixing.mall.base.enums.SysCfgCodeEnum;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.base.wrapper.Result;
import com.weixing.mall.base.wrapper.ResultUtil;
import com.weixing.mall.base.enums.IsEnableEnum;
import com.weixing.mall.base.enums.WhetherEnum;
import com.weixing.mall.core.support.auth.AgentAuth;
import com.weixing.mall.core.support.auth.AuthUtil;
import com.weixing.mall.core.support.auth.SysAuth;
import com.weixing.mall.core.utils.CommonUtil;
import com.weixing.mall.leaf.api.service.IdGenServiceRpc;
import com.weixing.mall.provider.api.model.dto.MemberAgentBindDto;
import com.weixing.mall.provider.api.model.dto.SaleAgentDto;
import com.weixing.mall.provider.api.model.enums.AgentLevelEnum;
import com.weixing.mall.provider.api.model.enums.IsOfficialEnum;
import com.weixing.mall.provider.api.model.enums.TreeRoleEnum;
import com.weixing.mall.provider.api.model.query.AgentInfoQuery;
import com.weixing.mall.provider.api.model.query.AgentMemberQuery;
import com.weixing.mall.provider.api.model.vo.*;
import com.weixing.mall.provider.api.service.MemberServiceRpc;
import com.weixing.mall.provider.api.service.SysConfigServiceFeign;
import com.weixing.mall.provider.api.service.SysUserRpcService;
import com.weixing.mall.provider.mapper.AgentMapper;
import com.weixing.mall.provider.model.domain.*;
import com.weixing.mall.provider.model.dto.AgentBasicEditDto;
import com.weixing.mall.provider.model.enums.AgentLogTypeEnum;
import com.weixing.mall.provider.model.enums.InfoPerfectEnum;
import com.weixing.mall.provider.model.query.AgentProfitQuery;
import com.weixing.mall.provider.model.query.AgentQuery;
import com.weixing.mall.provider.model.query.AgentTreeQuery;
import com.weixing.mall.provider.model.query.UpAgentQuery;
import com.weixing.mall.provider.model.vo.AgentTreeVo;
import com.weixing.mall.provider.model.vo.*;
import com.weixing.mall.provider.service.*;
import com.weixing.mall.provider.util.AgentUtil;
import com.weixing.mall.provider.util.InfoPerfectUtil;
import com.weixing.mall.util.CommUtil;
import com.weixing.mall.util.number.NumberPatternEnum;
import com.weixing.mall.util.number.NumberToRmbUtil;
import jodd.util.StringUtil;
import org.apache.logging.log4j.util.PropertySource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 代理商模块-代理商表 服务实现类
 * </p>
 *
 * @author Small
 * @since 2019-11-18
 */
@Service
public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements IAgentService {
    @Autowired
    private IAgentRuleService agentRuleService;
    @Autowired
    private SysUserRpcService sysUserRpcService;
    @Autowired
    private IdGenServiceRpc idGenServiceRpc;
    @Autowired
    private IAgentCommissionService agentCommissionService;
    @Autowired
    private IAgentRebateService agentRebateService;
    @Autowired
    private IAgentBonusService agentBonusService;
    @Autowired
    private MemberServiceRpc memberServiceRpc;
    @Autowired
    private IAgentInfoService agentInfoService;
    @Autowired
    private IAgentAccountService agentAccountService;
    @Autowired
    private IAgentSettleService agentSettleService;
    @Autowired
    private IAgentLogService agentLogService;
    @Autowired
    private SysConfigServiceFeign sysConfigServiceFeign;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveBasic(AgentBasicEditDto dto) {
        Agent agent = new Agent();
        agent.setId(dto.getId());
        agent.setMobile(dto.getMobile());
        agent.setWechatNum(dto.getWechatNum());
        agent.setWechatNickName(dto.getWechatNickName());
        agent.setAgentName(dto.getAgentName());
        agent.setAgentType(dto.getAgentType().getValue());
        agent.setEmail(dto.getEmail());
        agent.setCustomerBindTime(new Date());
        agent.setIsOfficial(dto.getIsOfficial().getValue());
        agent.setIsEnable(dto.getIsEnable().getValue());
        agent.setIsAdsAuth(dto.getIsAdsAuth().getValue());
        agent.setIsActive(dto.getIsActive().getValue());
        agent.setRemark(dto.getRemark());
        agent.setAgencyFeeYear(dto.getAgencyFeeYear());
        agent.setAgencyFeeMonth(dto.getAgencyFeeMonth());
        agent.setDiscount(dto.getDiscount());
        agent.setAdsLimit(dto.getAdsLimit());
        agent.setNickName(dto.getNickName());
        String mobile = agent.getMobile();
        if (null == dto.getId()) {
            agent.setPassword(CommonUtil.encryptPassword(dto.getPassword()));
            agent.setAgentLevel(dto.getAgentLevel().getValue());
            agent.setRebateRule(dto.getAgentLevel().getRebateRule().getValue());
            // 代理商编码，生成规则，顺序递增，8位不足补0
            long agentSn = idGenServiceRpc.segmentKey(IdGenTagEnum.AGENT_SN.getValue());

            agent.setAgentSn(String.valueOf(agentSn) + RandomUtil.randomNumbers(2));
            agent.setIsInfoPerfect(InfoPerfectUtil.add(InfoPerfectEnum.NONE.getValue(), InfoPerfectEnum.BASIC));
            if (IsOfficialEnum.PROBATION.getValue().equals(agent.getIsOfficial())) {
                agent.setMaturityTime(dto.getMaturityTime());
            } else {
                agent.setMaturityTime(new Date());
            }
            if (null == dto.getEffectTime()) {
                agent.setEffectTime(new Date());
            } else {
                agent.setEffectTime(dto.getEffectTime());
            }
            save(agent);
            // 设置代理商结构树
            Agent newAgent = new Agent();
            newAgent.setId(agent.getId());
            newAgent.setAgentTreePath(AgentUtil.calcAgentTreePath(agent));
            updateById(newAgent);
            // 创建代理商账户表
            AgentAccount agentAccount = new AgentAccount();
            agentAccount.setAgentId(agent.getId());
            agentAccountService.save(agentAccount);
            // 记录代理日志
            createAgentLog(agent);
        } else {
            Agent byId = getById(dto.getId());
            if (WhetherEnum.YES.getValue().equals(byId.getIsBind())) {
                if (!byId.getAgentLevel().equals(dto.getAgentLevel().getValue())) {
                    throw new BusinessException("已绑定过代理结构树，不允许修改代理商等级");
                }
            }
            if (0 != byId.getParentId()) {
                Agent parent = getById(byId.getParentId());
                if (parent.getDiscount().compareTo(dto.getDiscount()) >= 0) {
                    throw new BusinessException("代理折扣不能比父级代理折扣低，父级折扣：" + NumberToRmbUtil.format(parent.getDiscount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                }
            }
            if (StrUtil.isNotEmpty(agent.getWechatNum()) && checkWechat(agent.getWechatNum(), agent.getId())) {
                throw new BusinessException("微信号已存在");
            }
            if (IsOfficialEnum.PROBATION.getValue().equals(agent.getIsOfficial())) {
                agent.setMaturityTime(dto.getMaturityTime());
            }
            if (null != dto.getEffectTime()) {
                agent.setEffectTime(dto.getEffectTime());
            }
            updateById(agent);
        }
        // 会员绑定
        bindMember(dto, agent);
        return agent.getId();
    }

    private void createAgentLog(Agent agent) {
        AgentLog log = new AgentLog();
        log.setAgentId(agent.getId());
        log.setAgentSn(agent.getAgentSn());
        log.setAgentName(agent.getAgentName());
        log.setAgentLevel(agent.getAgentLevel());
        log.setMobile(agent.getMobile());
        log.setWechatNum(agent.getWechatNum());
        log.setOperatorId(AuthUtil.getSysExt().getUid());
        log.setOperatorName(AuthUtil.getSysExt().getRealName());
        log.setLogType(IsOfficialEnum.PROBATION.getValue().equals(agent.getIsOfficial()) ? AgentLogTypeEnum.SY.getValue() : AgentLogTypeEnum.XZZS.getValue());
        agentLogService.save(log);
    }

    /**
     * 校验微信号是否存在
     * 传代理ID的话代表排除代理本身的微信号查看是否重复 用于更新
     * 不传代理ID的话查询所有是否重复 用于新增
     *
     * @param wechatNum
     * @param agentId
     * @return true 存在  false  不存在
     */
    private boolean checkWechat(String wechatNum, Long agentId) {
        QueryWrapper<Agent> qw = new QueryWrapper<>();
        if (agentId != null) {
            qw.ne("id", agentId);
        }
        qw.eq("wechat_num", wechatNum);
        return count(qw) > 0 ? true : false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveBasicApply(AgentBasicEditDto dto) {
        Agent agent = new Agent();
        agent.setId(dto.getId());
        agent.setMobile(dto.getMobile());
        agent.setWechatNum(dto.getWechatNum());
        agent.setWechatNickName(dto.getWechatNickName());
        agent.setAgentName(dto.getAgentName());
        agent.setAgentType(dto.getAgentType().getValue());
        agent.setEmail(dto.getEmail());
        agent.setCustomerBindTime(new Date());
        agent.setIsOfficial(dto.getIsOfficial().getValue());
        agent.setIsEnable(dto.getIsEnable().getValue());
        agent.setIsAdsAuth(dto.getIsAdsAuth().getValue());
        agent.setIsActive(dto.getIsActive().getValue());
        agent.setRemark(dto.getRemark());
        agent.setAgencyFeeYear(dto.getAgencyFeeYear());
        agent.setAgencyFeeMonth(dto.getAgencyFeeMonth());
        agent.setAdsLimit(dto.getAdsLimit());
        agent.setNickName(dto.getNickName());
        Agent byId1 = getById(dto.getId());
        if (StringUtil.isEmpty(byId1.getAgentSn())) {
            long agentSn = idGenServiceRpc.segmentKey(IdGenTagEnum.AGENT_SN.getValue());
            agent.setAgentSn(String.valueOf(agentSn) + RandomUtil.randomNumbers(2));
        }
//        agent.setPassword(CommonUtil.encryptPassword(dto.getPassword()));
        agent.setAgentLevel(dto.getAgentLevel().getValue());
        agent.setRebateRule(dto.getAgentLevel().getRebateRule().getValue());
        AgentRule agentRule = agentRuleService.selectByLevelAndType(agent.getAgentLevel(), agent.getAgentType());
        if (null == agentRule) {
            throw new BusinessException("系统未配置该代理等级的折扣信息，请联系系统管理员确认！");
        }
        agent.setDiscount(agentRule.getDiscount());
        agent.setIsInfoPerfect(InfoPerfectUtil.add(InfoPerfectEnum.NONE.getValue(), InfoPerfectEnum.BASIC));
        if (IsOfficialEnum.PROBATION.getValue().equals(agent.getIsOfficial())) {
            agent.setMaturityTime(dto.getMaturityTime());
        } else {
            agent.setMaturityTime(new Date());
        }
        agent.setAgentTreePath(AgentUtil.calcAgentTreePath(agent));
        updateById(agent);
        // 创建代理商账户表
        AgentAccount agentAccount = new AgentAccount();
        agentAccount.setAgentId(agent.getId());
        agentAccountService.save(agentAccount);
        // 记录日志
        createAgentLog(agent);
        // 会员绑定
        bindMember(dto, agent);
        return agent.getId();
    }

    private void bindMember(AgentBasicEditDto dto, Agent agent) {
        MemberAgentBindDto bindDto = new MemberAgentBindDto();
        bindDto.setAgentId(agent.getId());
        bindDto.setAgentSn(agent.getAgentSn());
        bindDto.setAgentName(agent.getAgentName());
        bindDto.setPassword(dto.getPassword());
        bindDto.setMobile(agent.getMobile());
        Result result = memberServiceRpc.saveOrUpdateMember(bindDto);
        if (!result.isSuccess()) {
            throw new BusinessException("处理代理商和会员绑定关系时异常，请联系管理员处理");
        }
    }


    @Override
    public AgentVo selectByMobile(String mobile) {
        return baseMapper.selectByMobile(mobile);
    }

    @Override
    public AgentVo selectByAgentSn(String agentSn) {
        return baseMapper.selectByAgentSn(agentSn);
    }

    @Override
    public AgentVo selectByAgentInfo(AgentInfoQuery agentInfoQuery) {
        return baseMapper.selectByAgentInfo(agentInfoQuery);
    }

    @Override
    public IPage<AgentTreeVo> structuralTree(Page page, AgentTreeQuery agentTreeQuery) {
        IPage<AgentTreeVo> pageList = baseMapper.structuralTree(page, agentTreeQuery);
        if (pageList.getRecords().size() > 0) {
            for (AgentTreeVo agentTreeVo : pageList.getRecords()) {
                if (agentTreeVo != null) {
                    String addr = agentTreeVo.getProvince() + agentTreeVo.getCity();
                    agentTreeVo.setAddr(addr);
                }
            }
        }
        return pageList;
    }

    @Override
    public IPage<AgentTreeVo> structuralTree(Page page, AgentTreeQuery agentTreeQuery, AgentAuth auth) {
        IPage<AgentTreeVo> pageList = baseMapper.structuralTreeForAgent(page, agentTreeQuery, auth.getAid(), auth.getAlevel());
        if (pageList.getRecords().size() > 0) {
            for (AgentTreeVo agentTreeVo : pageList.getRecords()) {
                if (agentTreeVo != null) {
                    String addr = agentTreeVo.getProvince() + agentTreeVo.getCity();
                    agentTreeVo.setAddr(addr);
                }
            }
        }
        return pageList;
    }


    @Override
    public List<UpAgentVo> selectByUpAgent(UpAgentQuery upAgentQuery) {
        return baseMapper.selectByUpAgent(upAgentQuery);
    }

    @Override
    public AgentCustomerVo selectByIdAgentCustomer(Long agentId) {
        return baseMapper.selectByIdAgentCustomer(agentId);
    }

    @Override
    public List<AgentVo> selectByParentId(Long agentId) {
        return baseMapper.selectByParentId(agentId);
    }

    @Override
    public AgentVo selectById(Long agentId) {
        AgentVo agentVo = new AgentVo();
        Agent agent = baseMapper.selectById(agentId);
        BeanUtils.copyProperties(agent, agentVo);
        return agentVo;
    }

    @Override
    public List<Long> selectByCustomerIdAgentLevel(int parseInt, long currentUserId) {
        return baseMapper.selectByCustomerIdAgentLevel(parseInt, currentUserId);
    }

    @Override
    public AgentBasicEditVo selectBasicEditVo(Long id) {
        Agent agent = getById(id);
        AgentBasicEditVo dto = new AgentBasicEditVo();
        BeanUtils.copyProperties(agent, dto);
        return dto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void changeEnable(Long id, IsEnableEnum isEnable) {
        Agent agent = new Agent();
        agent.setId(id);
        agent.setIsEnable(isEnable.getValue());
        updateById(agent);
    }


    @Override
    public IPage<AgentTreeVo> findAgentTreeVoByPId(Page page, Long pid) {
        IPage<AgentTreeVo> pageList = baseMapper.findAgentTreeVoByPId(page, pid);
        if (pageList.getRecords().size() > 0) {
            for (AgentTreeVo agentTreeVo : pageList.getRecords()) {
                if (agentTreeVo != null) {
                    String addr = agentTreeVo.getProvince() + agentTreeVo.getCity();
                    agentTreeVo.setAddr(addr);
                }
            }
        }
        return pageList;
    }

    @Override
    public IPage agentMemberAddr(Page initMpPage, AgentMemberQuery agentMemberQuery) {
        return baseMapper.agentMemberAddr(initMpPage, agentMemberQuery);
    }

    @Override
    public List<Long> selectAgentIdByAgentLevel(int agentLevel) {
        return baseMapper.selectAgentIdByAgentLevel(agentLevel);
    }

    @Override
    public Long[] selectAgentTreeByParentId(Long agentId) {
        List<Agent> result = getIdsByParentId(Lists.newArrayList(), new Long[]{agentId});
        Long[] angentIds = listToArray(result);
        return angentIds;
    }

    private List<Agent> getIdsByParentId(List<Agent> tmpList, Long[] agentId) {
        List<Agent> tmp = baseMapper.selectList(new QueryWrapper<Agent>().in("parent_id", agentId));
        tmpList.addAll(tmp);
        if (null != tmp && tmp.size() != 0) {
            Long[] angentIds = listToArray(tmp);
            getIdsByParentId(tmpList, angentIds);
        }
        return tmpList;
    }

    private Long[] listToArray(List<Agent> tmp) {
        List<Long> angentIdList = tmp.stream().map(Agent -> Agent.getId()).collect(Collectors.toList());
        Long[] angentIds = new Long[angentIdList.size()];
        angentIdList.toArray(angentIds);
        return angentIds;
    }


    @Override
    public List<UpAgentVo> selectFormAgent(String agentName) {
        return baseMapper.selectFormAgent(agentName);
    }


    @Override
    public List<Agent> findByParentId(Long pid) {
        return list(new QueryWrapper<Agent>().eq("parent_id", pid));
    }

    @Override
    public Agent findByAgentSn(String agentSn) {
        return getOne(new QueryWrapper<Agent>().eq("agent_sn", agentSn));
    }

    @Override
    public Agent findByMobile(String mobile) {
        return getOne(new QueryWrapper<Agent>().eq("mobile", mobile));
    }

    /**
     * 方法描述:代理商绑定
     *
     * @param agent
     * @param parent
     * @return void
     * @Author Small
     * @Date 2020/3/16 18:55
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void agentBind(Agent agent, Agent parent) {
        agent.setIsBind(WhetherEnum.YES.getValue());
        agent.setCustomerId(parent.getCustomerId());
        agent.setCustomerName(parent.getCustomerName());
        agent.setCustomerBindTime(new Date());
        agent.setParentId(parent.getId());
        agent.setRebateRule(AgentUtil.calcAgentRebateRule(parent.getRebateRule(), agent.getAgentLevel().intValue()).getValue());
        agent.setAgentTreePath(AgentUtil.calcAgentTreePath(parent.getAgentTreePath(), agent));
        agent.setBonusGroupId(parent.getBonusGroupId());
        // 更新代理商结构树
        AgentUtil.updateAgentTree(agent);

//        updateAgentLog(agent);

        updateById(agent);
    }

    private void updateAgentLog(Agent agent) {
        AgentLog agentLog = agentLogService.findByAgentId(agent.getId());
        agentLog.setCustomerId(agent.getCustomerId());
        agentLog.setCustomerName(agent.getCustomerName());
        agentLogService.updateById(agentLog);
    }


    @Override
    public List<Agent> selectLastLevelListByAgentTreeNode(Agent agent, Integer oldLevel) {
        QueryWrapper<Agent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("agent_level", AgentLevelEnum.LEVEL_3.getValue());
        Integer agentLevel = null == oldLevel ? agent.getAgentLevel() : oldLevel;
        Long agentId = agent.getId();
        if (AgentLevelEnum.DEALER.getValue().equals(agentLevel)) {
            queryWrapper.eq("dealer_id", agentId);
        }
        if (AgentLevelEnum.LEVEL_1.getValue().equals(agentLevel)) {
            queryWrapper.eq("level1st", agentId);
        }
        if (AgentLevelEnum.LEVEL_2.getValue().equals(agentLevel)) {
            queryWrapper.eq("level2nd", agentId);
        }
        if (AgentLevelEnum.LEVEL_3.getValue().equals(agentLevel)) {
            queryWrapper.eq("level3rd", agentId);
        }
        if (AgentLevelEnum.LEVEL_4.getValue().equals(agentLevel)) {
            queryWrapper.eq("level4th", agentId);
        }
        return list(queryWrapper);
    }


    @Override
    public int countGroupPerson(Agent agent) {
        QueryWrapper<Agent> queryWrapper = new QueryWrapper<>();
        Integer agentLevel = agent.getAgentLevel();
        Long agentId = agent.getId();
        if (AgentLevelEnum.DEALER.getValue().equals(agentLevel)) {
            queryWrapper.eq("dealer_id", agentId);
        }
        if (AgentLevelEnum.LEVEL_1.getValue().equals(agentLevel)) {
            queryWrapper.eq("level1st", agentId);
        }
        if (AgentLevelEnum.LEVEL_2.getValue().equals(agentLevel)) {
            queryWrapper.eq("level2nd", agentId);
        }
        if (AgentLevelEnum.LEVEL_3.getValue().equals(agentLevel)) {
            queryWrapper.eq("level3rd", agentId);
        }
        if (AgentLevelEnum.LEVEL_4.getValue().equals(agentLevel)) {
            queryWrapper.eq("level4th", agentId);
        }
        return count(queryWrapper);
    }


    @Override
    public Page<AgentProfitVo> profitStatistic(Page page, AgentProfitQuery agentProfit) {
        String month = agentProfit.getMonth();
        QueryWrapper<Agent> queryWrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(agentProfit.getAgentName())) {
            queryWrapper.like("agent_name", agentProfit.getAgentName());
        }
        if (StringUtil.isNotEmpty(agentProfit.getMobile())) {
            queryWrapper.eq("mobile", agentProfit.getMobile());
        }
        if (null != agentProfit.getAgentId()) {
            queryWrapper.eq("agent_id", agentProfit.getAgentId());
        }
        IPage<Agent> pages = page(page, queryWrapper);
        List<Agent> records = pages.getRecords();
        List<AgentProfitVo> vos = Lists.newArrayList();
        if (CollUtil.isEmpty(records)) {
            AgentProfitVo vo = null;
            for (Agent agent : records) {
                long agentId = agent.getId();
                // 1、佣金
                BigDecimal commCnt = agentCommissionService.countComm(agentId, month);
                // 2、返利
                BigDecimal rebateCnt = agentRebateService.countRebate(agentId, month);
                // 3、分红
                BigDecimal bonusCnt = agentBonusService.countBonus(agentId, month);
                // 总金额
                BigDecimal totalCnt = NumberUtil.add(commCnt, rebateCnt, bonusCnt);
                vo = new AgentProfitVo();
                vo.setAgentId(agent.getId());
                vo.setAgentSn(agent.getAgentSn());
                vo.setAgentName(agent.getAgentName());
                vo.setTotalAmount(NumberToRmbUtil.defaultFormat(totalCnt));
                vo.setCommission(NumberToRmbUtil.defaultFormat(commCnt));
                vo.setBonus(NumberToRmbUtil.defaultFormat(bonusCnt));
                vo.setRebate(NumberToRmbUtil.defaultFormat(rebateCnt));
                vos.add(vo);
            }
        }
        Page<AgentProfitVo> resultPage = new Page<>(pages.getCurrent(), pages.getSize(), page.getTotal());
        resultPage.setRecords(vos);
        return resultPage;
    }

    @Override
    public IPage<AgentTableVo> selectOfPage(Page page, AgentMemberQuery agentMemberQuery) {
        return baseMapper.selectOfPage(page, agentMemberQuery);
    }

    @Override
    public List<AgentCustomerVo> selectByCustomerId(Long customerId) {
        return baseMapper.selectByCustomerId(customerId);
    }

    @Override
    public IPage<AgentVo> selectListOfPage(Page initMpPage, AgentQuery query, boolean forTree) {
        SysAuth sysExt = AuthUtil.getSysExt();
        if (!forTree) {
            Long uid = sysExt.getUid();
            String roles = sysExt.getRoles();
            // 如果是查询开户列表，并且前台没有传递客服id并且登录用户角色为客服时，只查询该客服下面的代理列表
            if (null == query.getCustomerId() && roles.contains(GlobalConstant.RoleCode.KF)) {
                query.setCustomerId(uid);
            }
            if(roles.contains(GlobalConstant.RoleCode.ADMIN)){
                query.setCustomerId(null);
            }
        } else {
            query.setAscOrder(WhetherEnum.NO);
        }
        query.setForTree(forTree ? IsEnableEnum.ENABLE : IsEnableEnum.DISABLE);


//        List<RoleVo> list = sysUserRpcService.getRoleById(uid).getData();
//        if (null == query.getCustomerId()) {
//            if (!forTree) {
//                boolean falg = true;
//                for (RoleVo vo : list) {
//                    if (vo.getRoleCode().equals(GlobalConstant.RoleCode.KF)) {
//                        falg = false;
//                        query.setCustomerId(uid);
//                        break;
//                    }
//                }
//                if (!falg) {
//                    query.setCustomerId(null);
//                }
//            } else {
//                query.setAscOrder(WhetherEnum.NO);
//            }
//            query.setForTree(forTree ? IsEnableEnum.ENABLE : IsEnableEnum.DISABLE);
//        } else {
//            query.setForTree(IsEnableEnum.ENABLE);
//        }


        IPage<AgentVo> page = baseMapper.selectListOfPage(initMpPage, query);
        if (null != page) {
            List<AgentVo> records = page.getRecords();
            if (CollUtil.isNotEmpty(records)) {
                records.forEach(record -> {
                    record.setMobile((null != sysExt && sysExt.isSensitive()) ? CommUtil.coverMobile(record.getMobile()) : record.getMobile());
                    if (forTree) {
                        int cnt = null == record.getAgentLevel() ? 1 : baseMapper.countGroupCnt(record.getId(), record.getAgentLevel().getValue());
                        record.setGroupCnt(cnt);
                    }
                });
            }
        }
        return page;
    }


    @Override
    public List<AgentTreeTableVo> tree(boolean isQueryAll) {
        SysAuth sysExt = AuthUtil.getSysExt();
        List<KefuVo> voList = Lists.newArrayList();
        if (isQueryAll) {
            Result<List<KefuVo>> kefuresult = sysUserRpcService.loadKefu();
            if (!kefuresult.isSuccess()) {
                throw new BusinessException("查询客服服务异常");
            }
            voList.addAll(kefuresult.getData());
        } else {
            Result<KefuVo> kefuresult = sysUserRpcService.loadKefuById(sysExt.getUid());
            if (!kefuresult.isSuccess()) {
                throw new BusinessException("查询客服服务异常");
            }
            voList.add(kefuresult.getData());
        }
        List<Agent> agents = listAll();
        // 最终返回的代理结构树
        List<AgentTreeTableVo> treeVos = Lists.newArrayList();
        if (CollUtil.isNotEmpty(voList)) {
            voList.forEach(kefuVo -> {
                AgentTreeTableVo treeVo = new AgentTreeTableVo();
                treeVo.setId(kefuVo.getId());
                treeVo.setR(TreeRoleEnum.KEFU.getValue());
                treeVo.setRn(TreeRoleEnum.KEFU.getDesp());
                treeVo.setN(kefuVo.getRealName());
                treeVo.setM(kefuVo.getMobile());
                treeVo.setMobile(sysExt.isSensitive() ? CommUtil.coverMobile(kefuVo.getMobile()) : kefuVo.getMobile());
                // 顶级节点
                List<AgentTreeTableVo> rootList = Lists.newArrayList();
                List<Agent> agents1 = agents.stream().filter((Agent a) -> a.getParentId().longValue() == 0 && a.getCustomerId().longValue() == kefuVo.getId().longValue()).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(agents1)) {
                    for (Agent agent : agents1) {
                        AgentTreeTableVo tV = new AgentTreeTableVo();
                        tV.setR(TreeRoleEnum.AGENT.getValue());
//                        tV.setRn(EnumUtil.getIEnum(AgentLevelEnum.class, agent.getAgentLevel()).getDesp());
                        tV.setRn(agent.getAgentLevel().toString());
                        tV.setM(agent.getMobile());
                        tV.setN(agent.getAgentName());
                        tV.setId(agent.getId());
                        tV.setMobile(sysExt.isSensitive() ? CommUtil.coverMobile(agent.getMobile()) : agent.getMobile());
                        //  递归包装child
                        wrapper(tV, sysExt, agents);
                        rootList.add(tV);
                    }
                }
                treeVo.setC(rootList);
                treeVos.add(treeVo);
                agents.removeAll(agents1);
            });

        }
        return treeVos;
    }

    private void wrapper(AgentTreeTableVo voNode, SysAuth sysAuth, List<Agent> agents) {
        List<AgentTreeTableVo> rootList = Lists.newArrayList();
        List<Agent> agents1 = agents.stream().filter((Agent a) -> a.getParentId().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(agents1)) {
            for (Agent agent : agents1) {
                AgentTreeTableVo tV = new AgentTreeTableVo();
                tV.setR(TreeRoleEnum.AGENT.getValue());
//                tV.setRn(EnumUtil.getIEnum(AgentLevelEnum.class, agent.getAgentLevel()).getDesp());
                tV.setRn(agent.getAgentLevel().toString());
                tV.setM(agent.getMobile());
                tV.setN(agent.getAgentName());
                tV.setId(agent.getId());
                if (null != sysAuth) {
                    tV.setMobile(sysAuth.isSensitive() ? CommUtil.coverMobile(agent.getMobile()) : agent.getMobile());
                } else {
                    tV.setMobile(agent.getMobile());
                }
                //  递归包装child
                wrapper(tV, sysAuth, agents);
                rootList.add(tV);
            }
            agents.removeAll(agents1);
        }
        voNode.setC(rootList);

    }

    @Override
    public Agent findByWechatNum(String wechatNum) {
        return getOne(new QueryWrapper<Agent>().eq("wechat_num", wechatNum).last("LIMIT 1"));
    }

    @Override
    public IPage<AgentRpcVo> selectChildByAgentId(Page page, long agentId, Integer agentLevel) {
        return baseMapper.selectChildByAgentId(page, agentId, agentLevel);
    }

    @Override
    public IPage<AgentRpcVo> selectAgentVoByCustomerId(Page page, long kefuId) {
        return baseMapper.selectAgentVoByCustomerId(page, kefuId);
    }

    @Override
    public List<Agent> selectObligee(Long kefuId) {
        return baseMapper.selectObligee(kefuId);
    }

    @Override
    public List<AgentVo> selectBonusAgent(Long agentId) {
        return baseMapper.selectBonusAgent(agentId);
    }

    @Override
    public List<Agent> selectObligeeChild(Long agentId) {
        return baseMapper.selectObligeeChild(agentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delAgent(Long id) {
        removeById(id);
        agentInfoService.remove(new QueryWrapper<AgentInfo>().eq("agent_id", id));
        agentAccountService.remove(new QueryWrapper<AgentAccount>().eq("agent_id", id));
        agentSettleService.remove(new QueryWrapper<AgentSettle>().eq("agent_id", id));
        // 清除会员代理身份
        Result result = memberServiceRpc.removeBindAgent(id);
        if (!result.isSuccess()) {
            throw new BusinessException(result.getMsg());
        }
    }

    @Override
    public List<Agent> listAll() {
        return baseMapper.listAll();
    }

    @Override
    public List<Agent> listAllByKefuId(Long uid) {
        return baseMapper.listAllByKefuId(uid);
    }

    @Override
    public List<Agent> listAllByAgentIdAndAgentLevel(long agentId, Integer agentLevel) {
        return baseMapper.listAllByAgentIdAndAgentLevel(agentId, agentLevel);
    }

    /*
     * 执行过期检查任务
     *
     *
     * */
    @Override
    public void expireTask() {
        List<Agent> agentList = baseMapper.selectList(new QueryWrapper<Agent>().lt("maturity_time", new Date()).eq("is_enable", WhetherEnum.YES.getValue()));
        List<AgentLog> logList = Lists.newArrayList();
        List<Agent> updateList = Lists.newArrayList();
        for (Agent agent : agentList) {
            Agent entity = new Agent();
            AgentLog agentLog = new AgentLog();
            BeanUtils.copyProperties(agent, agentLog);
            agentLog.setCreatedTime(new Date());
            if (agent.getIsOfficial().intValue() == WhetherEnum.NO.getValue().intValue()) {//试用代理商
                agentLog.setLogType(AgentLogTypeEnum.SYGQ.getValue());
            } else {
                agentLog.setLogType(AgentLogTypeEnum.ZSGQ.getValue());
            }
            agentLog.setAgentId(agent.getId());
            agentLog.setEffectStart(agent.getEffectTime());
            agentLog.setEffectEnd(agent.getMaturityTime());
            agentLog.setOperatorId(0L);
            agentLog.setOperatorName("系统扫描操作");
            entity.setIsEnable(WhetherEnum.NO.getValue());
            entity.setId(agent.getId());
            updateList.add(entity);
            logList.add(agentLog);
        }
        if (logList.size() != 0) {
            agentLogService.saveBatch(logList);
        }
        if (updateList.size() != 0) {
            updateBatchById(updateList);
        }
    }

    @Override
    public List<AgentTreeTableVo> treeForAgent(Long agentId) {
        Agent root = getById(agentId);
        List<Agent> agents = listAllByAgentIdAndAgentLevel(root.getId(), root.getAgentLevel());
        // 最终返回的代理结构树
        List<AgentTreeTableVo> treeVos = Lists.newArrayList();

        AgentTreeTableVo treeVo = new AgentTreeTableVo();
        treeVo.setId(root.getId());
        treeVo.setR(TreeRoleEnum.AGENT.getValue());
        treeVo.setRn(root.getAgentLevel().toString());
        treeVo.setN(root.getAgentName());
        treeVo.setM(root.getMobile());
        treeVo.setMobile(root.getMobile());
        wrapper(treeVo, null, agents);
        treeVos.add(treeVo);
        return treeVos;
    }

    @Override
    public List<Agent> selectObligor(Long kefuId) {
        return baseMapper.selectObligor(kefuId);
    }

    @Override
    public int countKefuGroupCnt(Long id) {
        return baseMapper.countKefuGroupCnt(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(Agent byId, String newPwd) {
        updateById(byId);
        Result result = memberServiceRpc.updatePwd(byId.getId(), newPwd);
        if (!result.isSuccess()) {
            throw new BusinessException("修改密码失败");
        }
    }

    @Override
    public IPage<AgentVo> selectListOfPageForAgent(Page initMpPage, AgentQuery query, boolean forTree) {
        Date now = new Date();
        query.setAscOrder(WhetherEnum.NO);
        IPage<AgentVo> page = baseMapper.selectListOfPage(initMpPage, query);
        if (null != page) {
            List<AgentVo> records = page.getRecords();
            if (CollUtil.isNotEmpty(records)) {

                Result<SysConfigVo> re = sysConfigServiceFeign.getByCode(SysCfgCodeEnum.AGENT_MOBILE_HIDE.getCode());
                boolean hide = re.isSuccess() ? re.getData().getCfgValue().intValue() == 1 : false;
                records.forEach(record -> {
                    record.setIsExpire(DateUtil.compare(now, record.getMaturityTime()) > 0 ? 1 : 0);
                    if (hide) {
                        record.setMobile(CommUtil.coverMobile(record.getMobile()));
                    }
                    if (forTree) {
                        int cnt = null == record.getAgentLevel() ? 1 : baseMapper.countGroupCnt(record.getId(), record.getAgentLevel().getValue());
                        record.setGroupCnt(cnt);
                    }
                });
            }
        }
        return page;
    }

    @Override
    public List<AgentBonusGroup> selectObligeeOwn(Long agentId) {
        return baseMapper.selectObligeeOwn(agentId);
    }

    @Override
    public int countTotalByIsOfficial(Integer value) {
        return baseMapper.countTotalByIsOfficial(value);
    }

    @Override
    public List<String> loadKefuMasterCid() {

        return baseMapper.loadKefuMasterCid();
    }

    /**
     * 加入黑名单
     *
     * @param agentId   代理商id
     * @param blackFlag 黑名单标识
     */
    @Override
    public Result pullOrDetachBlack(Long agentId, Integer blackFlag) {
        Agent agent = getById(agentId);
        if (null == agent) {
            return ResultUtil.error(ResultCodeEnum.CODE_10015003);
        }
        agent.setIsBlack(blackFlag);
        updateById(agent);
        return ResultUtil.success();
    }

    @Override
    public int countAgentGroupCnt(Long agentId, Integer agentLevel) {
        return baseMapper.countGroupCnt(agentId, agentLevel);
    }

    @Override
    public IPage<AgentRpcVo> selectChildByAgent(Page page, SaleAgentDto dto, Integer agentLevel) {
        return baseMapper.selectChildByAgent(page, dto, agentLevel);
    }

    @Override
    public List<Agent> selectEnableAll() {

        return baseMapper.selectEnableAll();
    }

    @Override
    public List<AgentTreeVo> getTop10AgentTeam() {
        List<Agent> agentList=list(new QueryWrapper<Agent>().eq("is_bind",1).eq("parent_id",0).eq("is_enable",1).gt(true,"maturity_time",new DateTime()));
        List<AgentTreeVo> agentTreeVoList=Lists.newArrayList();
        for(Agent agent:agentList){
            Integer conut=count(new QueryWrapper<Agent>().eq("is_bind",1).eq("is_enable",1).gt(true,"maturity_time",new DateTime()).eq("dealer_id",agent.getId()).or().eq("level1st",agent.getId()).or().eq("level2nd",agent.getId()).or().eq("level3rd",agent.getId()));
            AgentTreeVo vo=new AgentTreeVo();
            vo.setAgentName(agent.getAgentName());
            vo.setQuantity(conut);
            agentTreeVoList.add(vo);
        }
        agentTreeVoList=agentTreeVoList.stream().sorted(Comparator.comparing(AgentTreeVo::getQuantity).reversed())
                .collect(Collectors.toList());
        agentTreeVoList=  agentTreeVoList.subList(0,10);
        return agentTreeVoList;
    }

    @Override
    public int countTotalByIsEnable(Integer value) {
        return baseMapper.countTotalByIsEnable(value);
    }


    @Override
    public int countExpTotal() {
        return baseMapper.countExpTotal();
    }

}
